# encoding: utf-8
namespace :db do
  desc "Feed the database with location names from a XML file supplied by filename=/path/to/paikannimi.xml (optional: [counter=true])"
  task :feed_locations => :environment do
    require 'nokogiri'
    
    start_time = Time.now
    file = ENV['filename']
    doc = Nokogiri::XML::Reader(File.open(file)) # The XML file is supposedly huge so we're using Nokogiri reader
    fail_count = 0
    succ_count = 0
    
    # Disable logging for the 300 000 or so inserts
    # !!! Should be fixed not to disable logging globally
    old_logger = ActiveRecord::Base.logger
    ActiveRecord::Base.logger = nil
    
    # If the user hasn't specifically wanted the counter to be shown, it's disabled
    counter = ENV['counter'] || false
    counter_text = ""
    
    # For each of the nodes the Nokogiri reader reads...
    doc.each do |node|
      # ...react to those which have a name "pnr:kirjoitusasu", 'cos those are the lines we are looking for
      if node.name == "pnr:kirjoitusasu"
        location_name = node.inner_xml
        unless Location.find_by_name(location_name)
          loc = Location.new(:name => location_name, :search_name => location_name.fuzzify)
          if loc.save
            succ_count += 1
            unless counter == false
              STDOUT.flush # Force the print buffer to stdout
              print "\r" # Back to the beginning of line
              print " "*counter_text.size # Erasing the last printed line
              print "\r" #Back to the beginning again
              counter_text = "#{succ_count} locations"
              print counter_text # Prints the running count of locations succesfully saved into the db
            end
          else
            # !!! In case an error occurred, print the message to the user. Should probably put that into the log
            puts "#{location_name} didn't save, shieeeet"
            puts loc.errors.collect(&:full_messages).join("\n")
            fail_count += 1
          end
        end
      end
    end
    
    end_time = Time.now
    elapsed_minutes = ((end_time - start_time)/60).floor
    elapsed_seconds = ((end_time - start_time) - elapsed_minutes*60).round
    print "\n"
    puts "Added #{succ_count} new location names"
    puts "#{fail_count} failed"
    puts "Took #{elapsed_minutes} #{elapsed_minutes == 1 ? "minute" : "minutes"} #{elapsed_seconds} seconds"
    
    # Enable the logging again
    ActiveRecord::Base.logger = old_logger
  end
end
